﻿#region header

//  ***************************************************************************
// *                                LICENSE
//  ***************************************************************************
//  * "Haplous" .NET Simple 2D Game Framework
//  * 
//  * Copyright © Jonathan Evans 2014-2014
//  * 
//  * This program is free software; you can redistribute it and/or
//  * modify it under the terms of the GNU General Public License
//  * as published by the Free Software Foundation; either version 2
//  * of the License, or (at your option) any later version.
//  * 
//  * This program is distributed in the hope that it will be useful,
//  * but WITHOUT ANY WARRANTY; without even the implied warranty of
//  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  * GNU General Public License for more details.
//  * 
//  * You should have received a copy of the GNU General Public License
//  * along with this program; if not, write to the Free Software
//  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
//  * 
//  ***************************************************************************
//  * 
//  * Contact: opencollar@googlemail.com
//  * 
//  * Website: http://haplous.codeplex.com/
//  *
//  * NuGet:   http://www.nuget.org/packages/haplous/
//  *
//  * File:    Haplous/Haplous/BlockTemplateSelector.cs
//  *
//  ***************************************************************************

#endregion

using System.Diagnostics.CodeAnalysis;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

using Haplous.Presentation.ViewModel;

using JetBrains.Annotations;

namespace Haplous.Presentation
{
    /// <summary>
    ///     A template selector used to determine which template type to use to display various block types.
    /// </summary>
    [SuppressMessage("Microsoft.Performance", "CA1812:AvoidUninstantiatedInternalClasses")]
    [UsedImplicitly]
    public class BlockTemplateSelector : DataTemplateSelector
    {
        /// <summary>
        ///     When overridden in a derived class, returns a <see cref="T:System.Windows.DataTemplate" /> based on custom logic.
        /// </summary>
        /// <returns>
        ///     Returns a <see cref="T:System.Windows.DataTemplate" /> or null. The default value is null.
        /// </returns>
        /// <param name="item">The data object for which to select the template.</param>
        /// <param name="container">The data-bound object.</param>
        public override DataTemplate SelectTemplate(object item, [NotNull] DependencyObject container)
        {
            var parent = FindParent<GameArea>(container);
            if(parent == null)
                return null;

            if(item is TextBlockWrapper)
                return (DataTemplate)parent.Resources["TextBlockTemplate"];

            if(item is GraphicBlockWrapper)
                return (DataTemplate)parent.Resources["GraphicBlockTemplate"];

            return null;
        }

        [CanBeNull]
        private T FindParent<T>([CanBeNull] DependencyObject element) where T : UIElement
        {
            if(element == null)
                return null;

            var x = VisualTreeHelper.GetParent(element);
            var parent = x as T;
            if(parent != null)
                return parent;

            var control = element as FrameworkElement;

            if(control != null)
            {
                parent = control.Parent as T;
                if(parent != null)
                    return parent;
            }

            if(x != null)
                return (FindParent<T>(x));

            if(control != null)
                return (FindParent<T>(control.Parent));

            return null;
        }
    }
}